[iOS] JINS MEMEで各センサー値へアクセスしてみた
ガジェット大好き、田中孝明です。
同僚がJINS MEMEを借りてきたので1日だけ貸してもらいました。
その際に試してみたことをまとめてみました。
JINS MEME
JINS MEMEは以下のセンサー類を搭載した眼鏡型デバイスです。
■ 3点式眼電位センサー(特許取得済)
■ 3軸加速度センサー
■ 3軸ジャイロ(角速度)センサー
SDKを組み込むことで、Android / iOSのアプリケーションからBLEを利用して、姿勢、瞬き、目の動きなどを取ることができます。
実際に取れるイベントに関してはこちらを参考にしていただければと思います。
日本語のドキュメントやiOS向け JINS MEME SDK サンプルアプリなど、資料が豊富で、ちょっと動作を試してみたい時でもさほど詰まることはありませんでした。
プロジェクト作成準備
JINSアカウントの登録
iOSのSDKを組み込んで、センサーへのアクセスを試してみました。
当然ですが、JINS MEMEを用意する必要があります。
借りることも出来るそうですので、そちらのルートでもお試しいただければと思います。
SDKの利用にはJINS MEME DEVELOPERSへの開発者登録が必要です。
まずはJINSアカウントを登録しましょう。
アプリの登録
アカウント登録が終われば次にJINS MEMEを組み込むアプリを登録します。
必要な情報は以下の通りです。
■ アプリ名
■ アプリの説明
■ 開発者
アプリを登録することでアプリIDとアプリSecretが発効されます。
こちらは後ほど利用します。
XcodeプロジェクトへのSDKの追加
あとはこちらからiOSのSDKをダウンロードします。
ダウンロードしたファイルを解凍し、MEMELib.frameworkを事前に作成しておいたXcodeのプロジェクトに組み込みます。
以上でプロジェクト作成準備は完了です。
サンプルアプリ
MEMELibの初期化
SDKの利用にはアプリを登録した際に発効されたアプリIDとアプリSecretが必要です。
アプリケーションの起動時にMEMELib
のsetAppClientId
メソッドへアプリIDとアプリSecretの設定を行います。
private static let appId = "アプリ" private static let appSecret = "アプリSecret" ... func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { MEMELib.setAppClientId(AppDelegate.appId, clientSecret: AppDelegate.appSecret) return true }
JINS MEMEへの接続
MEMELibからのイベントに関してはMEMELibDelegate
のメソッドを利用します。
MEMELib.sharedInstance().delegate = self
MEMELib
のstartScanningPeripherals
メソッドをコールすることで、接続可能なJINS MEMEの検出が始まります。
let status: MEMEStatus = MEMELib.sharedInstance().startScanningPeripherals()
接続可能なJINS MEMEが見つかると、MEMELibDelegate
のmemePeripheralFound
メソッドにCBPeripheral
が返ってきます。
こちらを一旦保持しておきます。
// MARK: - MEMELibDelegate extension ScanViewController: MEMELibDelegate { func memePeripheralFound(_ peripheral: CBPeripheral!, withDeviceAddress address: String!) { if !memes.contains(peripheral) { memes.append(peripheral) } } ...
保持したをCBPeripheralをMEMELib
のconnect
メソッドの引数に渡すことで接続を開始します。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let peripheral = memes[indexPath.row] let status: MEMEStatus = MEMELib.sharedInstance().connect(peripheral) }
接続が完了しますと、MEMELibDelegate
のmemePeripheralConnected
メソッドに通知されます。
// MARK: - MEMELibDelegate extension ScanViewController: MEMELibDelegate { ... func memePeripheralConnected(_ peripheral: CBPeripheral!) { // Connected } ...
JINS MEMEへ正常に接続できていれば、MEMEStatus
がMEME_OK
となっています。
センサー値の取得
保持したCBPeripheralをMEMELib
のstartDataReport
メソッドをコールすることで、デバイスの値をリアルタイムで取得できるようになります。
let status: MEMEStatus = MEMELib.sharedInstance().startDataReport()
各センサーのデータは、MEMELibDelegate
のmemeRealTimeModeDataReceived
メソッドに通知されます。
// MARK: - MEMELibDelegate extension ScanViewController: MEMELibDelegate { ... func memeRealTimeModeDataReceived(_ data: MEMERealTimeData!) { // Received MEMERealTimeData } ...
受け取ったデータはMEMERealTimeData
というClass(Structでは無いので注意)のプロパティに格納されています。
各プロパティについてはリアルタイムモードで取得できるデータを参照してください。
センサー値を利用したアプリケーション
Gyro
MEMERealTimeData
のpitch
は頭部の上下運動を角度で返してくれます。
これを利用して居眠りを検知するとバイブで優しく起こしてくれるようにしました。
func memeRealTimeModeDataReceived(_ data: MEMERealTimeData!) { if data.pitch > 50 || data.pitch < -70 { print("sleep") AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) } }
ただ、上記の方法だとpitchが変わると即座に反応するので、filterを適用してしばらく同じ姿勢を繰り返すと動作するようにしたほうが良いかもしれません。
blinkSpeed
MEMERealTimeData
のblinkSpeed
は瞬きの速度を返してくれます。
これを利用して2度高速で瞬きすると、写真を撮影するようにしてみました。
var before: Date? ... func memeRealTimeModeDataReceived(_ data: MEMERealTimeData!) { if data.blinkSpeed > 0 { let now = Date() if let date = self?.before { let ti = now.timeIntervalSince(date) if ti < 0.3 { self.takePhoto() } } self.before = now } }
悪用ダメゼッタイ!
まとめ
こういうガジェットをハックしてアプリを作るのはワクワクしますね!
今後も面白そうなガジェットを試させていただける方がおられましたらご連絡お待ちしております!
参考文献
JINS MEME
SDK Docs
iOS向け JINS MEME SDK サンプルアプリ
リアルタイムモードで取得できるデータ